package Abilities

import (
	"PBMessage"
	//. "SGNet"
	. "GameLogic/Scene/Unit"

	proto "github.com/golang/protobuf/proto"
	"misc/NavMesh"
	xml "misc/dom4g"
	. "utils"
)

type AbiliMove struct {
	AbilityInfo
	TargetPos  Vec3
	IsMoveing  bool
	Nav        *NavMesh.NavMesh
	PathPoints []Vec3
	CurPointI  int
}

func (this *AbiliMove) GetId() int {
	return 0
}
func CreateAbiliMove(node *xml.Element) IAbility {
	return &AbiliMove{}
}
func (this *AbiliMove) GetAbilityInfo() *AbilityInfo {
	return &this.AbilityInfo
}

func (this *AbiliMove) OnEnter() {
	this.Nav = this.AbiliUnit.Scene.NavMesh
	this.AbiliUnit.GetCmdQueue().AddEvent(CommandType_Move, this.OnMoveCommandPush)
}

//处理单位的移动命令
func (this *AbiliMove) OnMoveCommandPush(ints []int32, floats []float32, strs []string) {
	if this.AbiliUnit.IsDie == true {
		return
	}
	this.TargetPos.Set(float64(floats[0]), float64(floats[1]), float64(floats[2]))
	this.PathPoints = this.Nav.FindPath(this.AbiliUnit.GetBaseUnit().Pos, this.TargetPos)
	this.CurPointI = 0
	this.IsMoveing = true
}

//每一帧向客户端发送一次
func (this *AbiliMove) Update() {
	if this.IsMoveing && this.AbiliUnit.Pos.DistanceFrom(&this.TargetPos) < 1 {
		this.IsMoveing = false
		this.AbiliUnit.Pos = this.TargetPos
		this.AbiliUnit.GetCmdQueue().Pop()
		this.SynPosToAllPlayer(false)
	}
	if this.IsMoveing == true {
		this.unitMove()
		this.SynPosToAllPlayer(true)
	}
}

func (this *AbiliMove) SynPosToAllPlayer(ismove bool) {
	gamePlayers := this.AbiliUnit.Scene.GamePlayers
	for _, player := range gamePlayers {
		if player == nil {
			continue
		}
		move := PBMessage.SC_AbilityMove{}
		move.PosX = proto.Float32(float32(this.AbiliUnit.Pos.X))
		move.PosY = proto.Float32(float32(0))
		move.PosZ = proto.Float32(float32(this.AbiliUnit.Pos.Z))
		move.IsMoveing = proto.Bool(ismove)
		move.UnitID = proto.String(this.AbiliUnit.GetBaseUnit().UUID)
		player.Sess.SendPacket(PBMessage.PBID_SC_AbilityMove, &move)

	}
}
func (this *AbiliMove) unitMove() {
	if this.IsMoveing == false {
		return
	}
	if this.CurPointI < len(this.PathPoints) {
		targetPos := this.PathPoints[this.CurPointI]
		dir := targetPos.Sub(&this.AbiliUnit.Pos)
		dir.Normalize()
		addPos := dir.MultNum(0.5)
		this.AbiliUnit.Pos.Add(addPos)
		if this.AbiliUnit.Pos.DistanceFrom(&targetPos) < 0.5 {
			this.CurPointI++
		}
	}

}
